﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WPF.TestEditor.Common;
using MahApps.Metro.Controls;
using WPF.TestEditor.Common.Interfaces;
using EasyStep.Business.Interfaces;
using System.Diagnostics;
using System.Timers;
using EasyStep.Data.Entities;
using AppProperties = WPF.TestEditor.Properties;
using System.ComponentModel;
using System.Windows.Threading;
using WPF.TestEditor.Controls;
using System.IO;


namespace WPF.TestEditor
{

    public partial class MainWindow : MetroWindow, ITestContextWindow
    {
        #region properties
        private Settings mSettings = new Settings(@"MainWindow");
        public Settings Settings
        {
            get
            {
                return mSettings;
            }
        }
        private ITestDataContext _TestDataContext;
        public ITestDataContext TestDataContext
        {
            get
            {
                return _TestDataContext;
            }
        }
        public TestInfo OriginalTest { get; set; }
        public TestInfo EditedTest { get; set; }
        private TestStep[] defaultTestSteps;
        public TestStep[] DefaultTestSteps
        {
            get
            {
                if (defaultTestSteps != null) return defaultTestSteps;
                defaultTestSteps = AppProperties.Settings.Default.DefaultTestSteps.Trim()
               .Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
               .Select(s => TestDataContext.TestStepManager.Convert(s))
               .Where(s => s != null)
               .ToArray();
                return defaultTestSteps;
            }
        }
        private TestEditor CurEditor;
        private TabItem PreviousItem = null;

        #endregion
        public MainWindow(ITestDataContext appDataContext)
        {
            _TestDataContext = appDataContext;
            statusClearTimer.Elapsed += new ElapsedEventHandler(statusClearTimer_Elapsed);
            UpdateStatus("Starting Test Editor, Main Window ...");
            InitializeComponent();

            topMnuNew.Click += new RoutedEventHandler(mnuNew_Click);
            mnuFileNew.Click += new RoutedEventHandler(mnuNew_Click);

            ttbSaveChanges.Click += new RoutedEventHandler(mnuFileSave_Click);
            topMnuSave.Click += new RoutedEventHandler(mnuFileSave_Click);
            mnuFileSave.Click += new RoutedEventHandler(mnuFileSave_Click);
            mnuFileSaveAs.Click += new RoutedEventHandler(mnuFileSaveAs_Click);
            topMnuExecute.Click += new RoutedEventHandler(topMnuExecute_Click);
            this.usrBrowsers.ExecuteTest += new EventHandler(usrBrowsers_ExecuteTest);

            mnuFileOpen.Click += new RoutedEventHandler(mnuFileOpen_Click);
            ttbFileOpen.Click += new RoutedEventHandler(mnuFileOpen_Click);
            txtCurTest.MouseDoubleClick += new MouseButtonEventHandler(txtCurTest_MouseDoubleClick);

            mnuExit.Click += new RoutedEventHandler(mnuExit_Click);
            this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);

            usrTestListEditor.DataChanged += new EventHandler(usrTestListEditor_DataChanged);
            usrTestTextEditor.DataChanged += new EventHandler(usrTestTextEditor_DataChanged);
            usrTestTextEditor.StatusChanges += new EventHandler<MessageArgs>(TestEditor_StatusChanges);
            usrTestListEditor.StatusChanges += new EventHandler<MessageArgs>(TestEditor_StatusChanges);
            CurEditor = TestEditor.None;
            InitializeTest();//load current test
            ApplySettings();//set settings+tab control
        }


        #region main actions
        private void ApplySettings()
        {
            UpdateStatus("Restoring menu settings from the config file");
            AppProperties.Settings.Default.Upgrade();
            mnuSettingsAutoConsts.IsChecked = !AppProperties.Settings.Default.ConstantCreateConfirmation;
            mnuExecuteContiniously.IsChecked = AppProperties.Settings.Default.ExecuteTestContiniously;
            mnuExecuteStopTestOnFirstError.IsChecked = AppProperties.Settings.Default.StopTestOnFirstError;
            mnuExecuteWithScreenShots.IsChecked = AppProperties.Settings.Default.MakeScreenShotsAfterEachStep;
            tabModes.SelectedIndex = AppProperties.Settings.Default.StartupTab;
            var actionsFolder = AppProperties.Settings.Default.ActionsFolder.TrimEnd('\\');
            mnuEngine.Header = "Test engine: " + System.IO.Path.GetFileName(actionsFolder);
            this.Title = "Easy Auto Test [ " + System.IO.Path.GetFileName(actionsFolder) + " ]";
            foreach (var d in System.IO.Directory.GetDirectories(System.IO.Path.GetDirectoryName(actionsFolder)))
            {
                var amenu = new MenuItem()
                {
                    Header = System.IO.Path.GetFileName(d.TrimEnd('\\')),
                    Tag = d,
                    IsCheckable = true
                };
                amenu.IsChecked = d.TrimEnd('\\').Equals(actionsFolder, StringComparison.OrdinalIgnoreCase);
                amenu.Checked += new RoutedEventHandler((s, e) =>
                {
                    var sender = s as MenuItem;

                    AppProperties.Settings.Default.ActionsFolder = sender.Tag as string;
                    AppProperties.Settings.Default.Save();
                    foreach (MenuItem mi in mnuEngine.Items)
                        if (sender != mi)
                            mi.IsChecked = false;
                    UpdateStatus("Test engine has been changed to:" + sender.Header.ToString() + "");
                    var r = MessageBox.Show("You have to restart application, to completely reload test engine\r\nOld test engine:\t\t" + System.IO.Path.GetFileName(actionsFolder) + "\r\nNew test engine:\t\t" + sender.Header.ToString(), "Information", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
                    if (r == MessageBoxResult.OK)
                    {
                        this.Close();
                        System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
                        System.Windows.Application.Current.Shutdown();
                    }
                });
                mnuEngine.Items.Add(amenu);
            }
            var curTheme = AppProperties.Settings.Default.CurrentTheme;
            foreach (var item in ThemeManager.DefaultAccents)
            {
                var amenu = new MenuItem()
                {
                    Header = item.Name,
                    Tag = item,
                    IsCheckable = true
                };

                amenu.IsChecked = item.Name.Equals(curTheme, StringComparison.OrdinalIgnoreCase);
                if (amenu.IsChecked)
                {
                    ThemeManager.ChangeTheme(App.Current, amenu.Tag as MahApps.Metro.Accent);
                    ThemeManager.ChangeTheme(this, amenu.Tag as MahApps.Metro.Accent);
                }
                amenu.Checked += new RoutedEventHandler(ThemeItem_Checked);
                mnuCurTheme.Items.Add(amenu);
            }
        }
        private void ThemeItem_Checked(object s, EventArgs e)
        {
            var sender = s as MenuItem;
            var accent = sender.Tag as MahApps.Metro.Accent;
            AppProperties.Settings.Default.Upgrade();
            AppProperties.Settings.Default.CurrentTheme = accent.Name;
            AppProperties.Settings.Default.Save();
            AppProperties.Settings.Default.Upgrade();
            UpdateStatus("Theme has been changed to:" + sender.Header.ToString() + "");
            this.Close();
            System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
            System.Windows.Application.Current.Shutdown();
        }

        private void InitializeTest()
        {
            UpdateStatus("Load current test data");
            if (!string.IsNullOrEmpty(TestDataContext.CurrentTest))
            {
                UpdateStatus("Load test file, project path:{0}, test name:{1}", new object[] { TestDataContext.CurrentProject, TestDataContext.CurrentTest });
                OriginalTest = TestDataContext.TestInfoManager.GetTest(TestDataContext.CurrentProject, TestDataContext.CurrentTest, true);
                OriginalTest = OriginalTest != null ? OriginalTest : TestDataContext.TestInfoManager.Create(
                    new TestInfo() { Name = TestDataContext.CurrentTest, Project = TestDataContext.CurrentProject }
                );
                EditedTest = TestDataContext.TestInfoManager.GetTest(TestDataContext.CurrentProject, TestDataContext.CurrentTest, true);
                UpdateStatus("Test file has been completely loaded");
            }
            else
            {
                OriginalTest = new TestInfo() { Steps = new TestStep[] { } };
                EditedTest = new TestInfo() { Steps = DefaultTestSteps, Name = TestDataContext.CurrentTest, Project = TestDataContext.CurrentProject };
                UpdateStatus("Test file hasn't been specified - empty test template has been shown");
            }
            ShowSelectedTestInfo();

            CurEditor = TestEditor.None;
        }

        private void CreateNewTest()
        {
            if (!ConfirmAndSaveChanges(false)) return;
            TestDataContext.CurrentTest = string.Empty;
            InitializeTest();
            SetupRightEditorTab();
        }

        private void OpenOtherTest()
        {
            if (!ConfirmAndSaveChanges(false)) return;

            var filedlg = new Microsoft.Win32.OpenFileDialog();
            filedlg.Title = "Choose test scenario file";
            filedlg.InitialDirectory = TestDataContext.CurrentProject;

            filedlg.Filter = "All files (*.test.csv)|*.test.csv";
            filedlg.FilterIndex = 2;
            filedlg.RestoreDirectory = true;
            if (filedlg.ShowDialog().Value)
            {
                TestDataContext.CurrentTest = System.IO.Path.GetFileName(filedlg.FileName);
                TestDataContext.CurrentProject = System.IO.Path.GetDirectoryName(filedlg.FileName);
                InitializeTest();
                SetupRightEditorTab();
                UpdateStatus(string.Format("new test file has been chosen to edit:{0} and loaded into editor", filedlg.FileName));
            }
        }

        private void ExecuteCurrentTest(bool quick)
        {
            var data = EditedTest;
            this.Opacity = 0.25;
            this.ShowInTaskbar = false;

            var browsers = this.usrBrowsers.Selected;
            quick = quick || browsers.Length > 0;
            var w = new ExecuteTestWindow(data, this.TestDataContext, browsers, quick);
            w.ShowDialog();
            this.Opacity = 1;
            this.ShowInTaskbar = true;
            if (tabPageHistoryMode.IsSelected)
                tabPageHistoryMode.IsSelected = false;

            tabPageHistoryMode.IsSelected = true;

        }

        protected bool SaveTest(TestInfo dataToSave, bool toCurrentFile = true)
        {
            UpdateStatus(string.Format("start to save test to current file?:{0}", toCurrentFile));
            if (!toCurrentFile || string.IsNullOrEmpty(dataToSave.Name))
            {
                var fdlg = new Microsoft.Win32.SaveFileDialog();
                fdlg.Title = "Save as ...";
                fdlg.InitialDirectory = TestDataContext.CurrentProject;
                fdlg.Filter = "All files (*.test.csv)|*.test.csv";
                fdlg.FilterIndex = 2;

                fdlg.RestoreDirectory = true;
                if (fdlg.ShowDialog().Value)
                {
                    dataToSave = dataToSave != null ? dataToSave : EditedTest;
                    UpdateStatus(string.Format("Been chosen new file to save:{0}, previous was:{1}\\{2}", fdlg.FileName, TestDataContext.CurrentProject, TestDataContext.CurrentTest));
                    TestDataContext.CurrentTest = System.IO.Path.GetFileName(fdlg.FileName);
                    TestDataContext.CurrentProject = System.IO.Path.GetDirectoryName(fdlg.FileName);
                    dataToSave.Name = TestDataContext.CurrentTest;
                    dataToSave.Project = TestDataContext.CurrentProject;
                    var existing = TestDataContext.TestInfoManager.GetTest(TestDataContext.CurrentProject, TestDataContext.CurrentTest);
                    UpdateStatus(string.Format("chosen file exist?{0} - if true it have to be updated, otherwise have to be created new:{2}\\{1}", fdlg.FileName, TestDataContext.CurrentTest, TestDataContext.CurrentProject));
                    if (existing != null)
                        TestDataContext.TestInfoManager.Update(dataToSave);
                    else
                        TestDataContext.TestInfoManager.Create(dataToSave);

                }
                else
                {
                    UpdateStatus(string.Format("user have canceled saving test to file:{0}\\{1}", TestDataContext.CurrentProject, TestDataContext.CurrentTest));
                    return false;
                }
            }
            else
            {
                UpdateStatus(string.Format("saving to current file:{0}\\{1}", TestDataContext.CurrentProject, dataToSave.Name));
                if (TestDataContext.TestInfoManager.GetTest() != null)
                    TestDataContext.TestInfoManager.Update(dataToSave);
                else
                    TestDataContext.TestInfoManager.Create(dataToSave);

            }
            SetupRightEditorTab();
            InitializeTest();
            return true;
        }
        private void SaveConstants()
        {
            var result = new List<TestConst>();
            var text = (txtConstTextEditor.Text ?? "").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            if (text.Length > 0)
                text.ToList().ForEach(l =>
                {
                    var c = TestDataContext.ConstantsManager.Convert(l);
                    if (c != null) result.Add(c);
                });
            UpdateStatus("Trying to save constants changes...");
            TestDataContext.ConstantsManager.UpdateAll(result);
            UpdateStatus("Constants data has been saved.");
        }
        private void SetupRightEditorTab()
        {//setup right tab
            var selTab = tabModes.SelectedItem as TabItem;

            if (CurEditor == TestEditor.TextBox || CurEditor == TestEditor.None)
            {
                if (!tabPageTextMode.IsSelected) tabPageTextMode.IsSelected = true;
                else BindAppropriateControlWithData(tabPageTextMode);
            }
            else
            {
                if (!tabPageListMode.IsSelected) tabPageListMode.IsSelected = true;
                else BindAppropriateControlWithData(tabPageListMode);
            }
        }
        #region Data initializing

        /// <summary>
        /// refresh controls with data
        /// </summary>
        /// <param name="dataToBind">could be empty: then data will be taken from other control then current (form or textbox)</param>
        private void BindAppropriateControlWithData(TabItem selectedTab)
        {
            //var selectedTab = tabModes.SelectedItem as TabItem;
            if (selectedTab == tabPageConstansMode)
            {
                BindConstants(false);
            }
            else if (selectedTab == tabPageHistoryMode)
            {
                BindHistory(selectedTab);
            }
            else if (selectedTab == tabPageListMode)
            {
                usrTestListEditor.InitEditor(EditedTest);
                CurEditor = TestEditor.ListBox;
            }
            else if (selectedTab == tabPageTextMode)
            {

                usrTestTextEditor.RefreshTest(EditedTest);
                CurEditor = TestEditor.TextBox;
            }
            else
                TestDataContext.Log.Error("Can't determinate tab page functionality to refresh");
        }



        private void BindHistory(TabItem selectedTab)
        {
            this.hsrViewer.ReInitEditor();
        }

        private bool BindConstants(bool inBackground)
        {
            //return ShowProcessing("Initializing constant editor", (e) =>
            //{
            var sb = new StringBuilder();
            var consts = TestDataContext.ConstantsManager.GetAll().ToList();
            consts.ForEach(c => sb.AppendLine(TestDataContext.ConstantsManager.Convert(c)));

            Action a = () =>
            {
                UpdateStatus("Been found {0} constants to edit", new object[] { consts.Count });
                txtConstTextEditor.Text = sb.ToString();
            };
            this.Dispatcher.Invoke(a);
            return true;
            //});
        }

        #endregion
        #endregion

        #region menu actions, events
        void mnuNew_Click(object sender, RoutedEventArgs e)
        {
            TestDataContext.Log.Debug("main window:mnuNew_Click");
            CreateNewTest();
        }

        void mnuFileSave_Click(object sender, RoutedEventArgs e)
        {
            TestDataContext.Log.Debug("main window:mnuFileSave_Click");
            if (tabPageTextMode.IsSelected || tabPageListMode.IsSelected)
                ConfirmAndSaveChanges(true);
            else if (tabPageConstansMode.IsSelected)
                SaveConstants();
        }
        void mnuFileSaveAs_Click(object sender, RoutedEventArgs e)
        {
            TestDataContext.Log.Debug("main window:mnuFileSaveAs_Click");
            if (tabPageTextMode.IsSelected || tabPageListMode.IsSelected)
                SaveTest(null, false);
            else if (tabPageConstansMode.IsSelected)
                SaveConstants();
        }
        void txtCurTest_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            TestDataContext.Log.Debug("main window:txtCurTest_MouseDoubleClick");
            OpenOtherTest();
        }
        void mnuFileOpen_Click(object sender, RoutedEventArgs e)
        {
            TestDataContext.Log.Debug("main window:mnuFileOpen_Click");
            OpenOtherTest();
        }
        void topMnuExecute_Click(object sender, RoutedEventArgs e)
        {
            TestDataContext.Log.Debug("main window:topMnuExecute_Click");
            ExecuteCurrentTest(true);
        }
        private void usrBrowsers_ExecuteTest(object sender, EventArgs e)
        {
            TestDataContext.Log.Debug("main window:usrBrowsers_ExecuteTest");
            ExecuteCurrentTest(true);
        }


        void mnuExit_Click(object sender, RoutedEventArgs e)
        {
            UpdateStatus("main window:mnuExit_Click");
            this.Close();
        }
        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            TestDataContext.Log.Info("closing main window");
            AppProperties.Settings.Default.Upgrade();
            AppProperties.Settings.Default.StartupTab = tabModes.SelectedIndex;
            AppProperties.Settings.Default.ConstantCreateConfirmation = !mnuSettingsAutoConsts.IsChecked;
            AppProperties.Settings.Default.HistoryTreeWidth = hsrViewer.LeftColumnWidth;
            AppProperties.Settings.Default.ExecuteTestContiniously = mnuExecuteContiniously.IsChecked;
            AppProperties.Settings.Default.MakeScreenShotsAfterEachStep = mnuExecuteWithScreenShots.IsChecked;
            AppProperties.Settings.Default.StopTestOnFirstError = mnuExecuteStopTestOnFirstError.IsChecked;
            if (!string.IsNullOrEmpty(TestDataContext.CurrentTest))
                AppProperties.Settings.Default.LastOpenedTest = System.IO.Path.Combine(TestDataContext.CurrentProject, TestDataContext.CurrentTest);
            AppProperties.Settings.Default.Save();
            AppProperties.Settings.Default.Upgrade();
        }

        private void tabModes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!(e.Source is TabControl)) return;

            e.Handled = true;
            var curIndex = tabModes.SelectedIndex;
            var selectedTab = (tabModes.SelectedItem as TabItem);
            if (selectedTab == null) return;
            UpdateStatus("has been shown [{0}] tab page", new object[] { selectedTab.Header });

            try
            {
                if (PreviousItem == tabPageConstansMode)
                    SaveConstants();

                BindAppropriateControlWithData(selectedTab);
                PreviousItem = selectedTab;
            }
            catch (Exception ex)
            {
                TestDataContext.Log.Fatal("Error during show control on tab:" + curIndex, ex);
                MessageBox.Show("Can't fill control with data!\r\n\r\n" + ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
            }          
        }
        void mnuViewMode_Checked(object sender, RoutedEventArgs e)
        {
            var c = sender as MenuItem;
            int itemindex;
            if (!c.IsChecked || !int.TryParse(c.Tag == null ? "" : c.Tag.ToString(), out itemindex)) return;
            if (tabModes.SelectedIndex != itemindex)
            {
                UpdateStatus("(menu)have to be selected other tab page [{0}]", new object[] { itemindex });
                tabModes.SelectedIndex = itemindex;
            }
        }
        void mnuExecute_Checked(object sender, RoutedEventArgs e)
        {
            var c = sender as MenuItem;
            var tag = c.Tag as string;
            switch (tag)
            {
                case "0": AppProperties.Settings.Default.ExecuteTestContiniously = c.IsChecked; break;
                case "1": AppProperties.Settings.Default.MakeScreenShotsAfterEachStep = c.IsChecked; break;
                case "2": AppProperties.Settings.Default.StopTestOnFirstError = c.IsChecked; break;
                default:
                    break;
            }
            AppProperties.Settings.Default.Save();
            AppProperties.Settings.Default.Upgrade();
        }

        void TestEditor_StatusChanges(object sender, MessageArgs e)
        {
            UpdateStatus(e.Message, e.FormatParams);
        }

        void usrTestTextEditor_DataChanged(object sender, EventArgs e)
        {
            EditedTest = (sender as TestTextEditor).Data;
            EditedTest.Name = TestDataContext.CurrentTest;
            EditedTest.Project = TestDataContext.CurrentProject;
        }

        void usrTestListEditor_DataChanged(object sender, EventArgs e)
        {
            EditedTest = (sender as TestListEditor).Data;
            EditedTest.Name = TestDataContext.CurrentTest;
            EditedTest.Project = TestDataContext.CurrentProject;
        }


        #endregion

        #region Help actions
        #region status bar
        Timer statusClearTimer = new Timer() { Interval = 2500 };
        [DebuggerHidden]
        [DebuggerStepThrough]
        void statusClearTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (this.tssLabelInfo)
            {
                Action a = () =>
                {
                    tssLabelInfo.Text = "";
                    statusClearTimer.Stop();
                };
                tssLabelInfo.Dispatcher.Invoke(a);
            }
        }
        [DebuggerStepThrough]
        private void UpdateStatus(string message, params object[] formatParams)
        {
            statusClearTimer.Stop();
            message = formatParams == null || formatParams.Length == 0 ? message : string.Format(message, formatParams);
            TestDataContext.Log.Debug(message);
            if (tssLabelInfo != null) tssLabelInfo.Text = message;
            statusClearTimer.Start();
        }
        #endregion
        [DebuggerHidden]
        [DebuggerStepThrough]
        private void ShowSelectedTestInfo(string testname = null)
        {
            string curEnvironment = !string.IsNullOrEmpty(TestDataContext.Environment) ? " [" + TestDataContext.Environment + "]" : "";
            string curProj = System.IO.Path.GetFileName(TestDataContext.CurrentProject.TrimEnd('\\'));
            string curTest = testname != null ? testname : !string.IsNullOrEmpty(OriginalTest.Name) ? OriginalTest.Name : "new test - 1";
            UpdateStatus(string.Format("cur environment:{0} \\cur project: {1} \\cur test: {2}", curEnvironment, curProj, curTest));
            txtCurTest.Text = string.Format("{0}\\{1}\\{2}", curEnvironment, curProj, curTest);
        }
        [DebuggerHidden]
        [DebuggerStepThrough]
        private void CheckViewMenuItem(int index)
        {
            foreach (var item in mnuViewAndHelp.Items)
            {
                var mi = (item as MenuItem);
                int itemIndex = 0;
                if (mi != null && int.TryParse(mi.Tag == null ? "" : mi.Tag.ToString(), out itemIndex))
                    if (mi.IsChecked != (itemIndex == index))
                        mi.IsChecked = itemIndex == index;
            }
        }

        //[DebuggerHidden]
        /// !!!             have a problem with synch      !!!  
        //private bool ShowProcessing(string title, Func<ProcessingEventArgs, bool> onProcessing)
        //{
        //    bool result = true;
        //    var p=new Processing(this, title, onProcessing);
        //    try
        //    {
        //        p.ShowDialog();
        //    }
        //    catch (Exception ex)
        //    {
        //        TestDataContext.Log.Fatal("Processing instruction has been canceled, because error!", ex);
        //        result=false;
        //    }
        //    p = null;
        //    return result;
        //}
        private bool BintTestEditorWithData(ProcessingEventArgs e, TestEditor forEditor, TestInfo data, Func<TestInfo, bool> onUpdateEditor, bool inBackground = false)
        {
            e.InvokeProgress("get currently edited data...", 10);
            if (data == null)
                data = e.Cancel ? null : EditedTest;
            e.InvokeProgress("initialize editor...", 50);

            if (data != null && !e.Cancel)
                try
                {
                    onUpdateEditor(data);
                }
                catch (Exception ex)
                {
                    TestDataContext.Log.Fatal("Can't bind test editor with data:", ex);
                }
            else
                TestDataContext.Log.Debug("Data editor haven't updated. Reason: cancel, or not needed");
            e.InvokeProgress("show editor...", 90);

            return !e.Cancel;
        }



        /// <summary>
        /// confirmation message will be shown
        /// </summary>
        /// <returns>false - when user want to stop any other actions...</returns>
        private bool ConfirmAndSaveChanges(bool saveWithoutConfirmation)
        {
            if (Compare(OriginalTest, EditedTest)) return true;
            MessageBoxResult result = (saveWithoutConfirmation)
                ? MessageBoxResult.Yes
                : MessageBox.Show("Unsaved changed have been detected\r\n Do you want to save them?", "Save changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
            if (result == MessageBoxResult.Yes)
                SaveTest(EditedTest, true);
            return result != MessageBoxResult.Cancel;
        }

        private bool Compare(TestInfo test1, TestInfo test2)
        {
            if (test1 == null && test2 == null) return true;
            if (test1 == null || test2 == null) return false;
            if (test1.Steps == null && test2.Steps == null) return true;
            if (test1.Steps == null || test2.Steps == null) return false;
            int test1StepsCount = test1.Steps.Count();
            if (test1StepsCount != test2.Steps.Count()) return false;
            var result = true;
            for (int i = 0; i < test1StepsCount; i++)
            {
                var tstep1 = TestDataContext.TestStepManager.Convert(test1.Steps.ElementAt(i)) ?? "";
                var tstep2 = TestDataContext.TestStepManager.Convert(test2.Steps.ElementAt(i)) ?? "";
                var identical = tstep1.Equals(tstep2);
                if (!identical)
                {
                    result = false;
                    break;
                }
            }
            return result;
        }

        #endregion

    }


    public enum TestEditor
    {
        None = -1,
        TextBox = 0,
        ListBox = 1
    }
}
